package com.android.hedgehog.bots;

import java.util.List;
import java.util.Random;

import android.graphics.Color;

import com.android.hedgehog.Assets;
import com.android.hedgehog.framework.Game;
import com.android.hedgehog.framework.Graphics;
import com.android.hedgehog.framework.Input.TouchEvent;

public class Bot {
	public enum Phase {
		Standby, Compute, Respond
	}

	Random rand = new Random();
	Graphics graphics;
	BotConfigurations data = new BotConfigurations();
	public int botScore;
	public Phase phase;
	float standbyTime;
	int botNumber; // 0-7
	int spriteCounter; // starts from 0
	final static int xCorner = 300;
	final static int yCorner = 215;
	final int yPos;
	final int width;
	final int height;
	final float agility;
	final int totalStandbySprites;
	final int calculateSprite;
	final int failSprite;
	public int selected;
	float speed;
	int totalHits, totalMisses;
	float computeTime;
	final int computeTimeLimit = 13;
	float accuracy;
	int finalAccuracy;
	float attackInstance;
	int questionMarkPos;
	boolean attackOccasion;
	public boolean correct;
	Game game;
	boolean hacked;
	public String name;
	public boolean highlighted;

	public Bot(Game game, int botNumber) {
		this.game = game;
		graphics = game.getGraphics();
		this.botNumber = botNumber;
		yPos = data.startingY[botNumber];
		width = data.width[botNumber];
		height = data.height[botNumber];
		spriteCounter = 0;
		agility = data.agility[botNumber];
		totalStandbySprites = data.totalStandbySprites[botNumber];
		calculateSprite = data.calculateIndex[botNumber];
		failSprite = data.failIndex[botNumber];
		name = data.names[botNumber];
		phase = Phase.Standby;

	}

	public void update(List<TouchEvent> touchEvents, float deltaTime) {

		if (phase == Phase.Standby)
			updateStandby(deltaTime);
		if (phase == Phase.Compute)
			updateCompute(touchEvents, deltaTime);
		if (phase == Phase.Respond)
			updateRespond(deltaTime);

	}

	private void updateStandby(float deltaTime) {
		standbyTime += deltaTime;

		if (standbyTime > agility) {
			spriteCounter++;
			standbyTime = 0.0f;
			if (spriteCounter == (totalStandbySprites+1))
				spriteCounter = 0;
		}
	}

	private void updateCompute(List<TouchEvent> touchEvents, float deltaTime) {

		computeTime += deltaTime;
		accuracy = (computeTime * speed);
		accuracy -= (totalHits * 8);
		accuracy += (totalMisses * 3);

		if (computeTime > attackInstance) { // SPRITE SWITCH
			hacked = false;
			attackInstance += .6;
			questionMarkPos = 210 + rand.nextInt(70);

			if (rand.nextInt(101) > 75)
				attackOccasion = true;
			else
				attackOccasion = false;

		} // SPRITE SWITCH

		if (computeTime > computeTimeLimit || accuracy >= 100) { // OVER
			computeTime = 0;
			attackInstance = 0;
			totalHits = 0;
			totalMisses = 0;
			highlighted=false;
			updateScore();
		}// OVER

		// *******************HACK ATTACK

		int len = touchEvents.size();
		for (int i = 0; i < len; i++) {// FOR
			TouchEvent event = touchEvents.get(i);
			if (event.x > 60 && event.x < 260 && event.y > 385 && event.y < 465
					&& (event.type == TouchEvent.TOUCH_DRAGGED || event.type == TouchEvent.TOUCH_DOWN)) {
				highlighted = true;
			} else {
				highlighted = false;
			}
			if (event.x > 60 && event.x < 260 && event.y > 385 && event.y < 465) { 
				if (event.type == TouchEvent.TOUCH_UP) { // TOUCH UP
					if (attackOccasion == false) {
						totalMisses++;
					} else {
						totalHits++;
						hacked = true;
						attackOccasion = false; // protects repeat hits
					}
				}// UP
			}

		}

		// ********************HACK ATTACK

	}

	private void updateScore() { // 1 Time run
		if (accuracy > 100)
			accuracy = 100;
		if (accuracy < 0)
			accuracy = 0;

		if ((accuracy+rand.nextInt(26))>78) {
			correct = true;
			botScore += selected;
		} else {
			correct = false;
		}

		phase = Phase.Respond;
	} // 1 time run

	private void updateRespond(float deltaTime) {

	}

	// ***************************PRESENT*****************************

	public void present() {
		graphics.drawUniversalText("S:" + selected + " A:" + (int)accuracy, 1, true, 30,
				100, 11, 255, Color.WHITE); // test
		graphics.drawUniversalText("H:" + totalHits + " M:" + totalMisses, 1, true, 30, 115, 11, 255,
				Color.WHITE); // test2
		if (phase == Phase.Standby)
			presentStandby();
		if (phase == Phase.Compute)
			presentCompute();
		if (phase == Phase.Respond)
			presentRespond();
	}

	private void presentStandby() {
		graphics.drawPixmap(Assets.bottest, xCorner - width, yCorner - height, spriteCounter * width, yPos,
				width, height);

	}

	private void presentCompute() {
		if (!hacked) {
			graphics.drawPixmap(Assets.bottest, xCorner - width, yCorner - height, calculateSprite * width,
					yPos, width, height);
		} else {
			graphics.drawPixmap(Assets.bottest, xCorner - width, yCorner - height, failSprite * width, yPos,
					width, height);
		}

		if (attackOccasion) { // ? Mark
			graphics.drawUniversalText("?", 2, true, questionMarkPos, 210 - height, 48, 255, Color.BLUE);
		} else {
			graphics.drawUniversalText("?", 2, true, questionMarkPos, 210 - height, 48, 255, Color.GREEN);
		}// ? Mark

		if (highlighted)
			graphics.drawUniversalRect(60, 385, 200, 80, false, true, 1, 100, Color.WHITE);

		graphics.drawUniversalRect(60, 385, 200, 80, false, false, 9, 255, Color.GRAY);
		graphics.drawUniversalText("HACK", 2, true, 160, 450, 54, 255, Color.GRAY);

		for (int i = 0; i < accuracy; i++) {
			graphics.drawLine(70 + i, 63, 70 + i, 78, Color.RED);
		}
		graphics.drawUniversalRect(70, 63, 100, 15, false, false, 3, 255, Color.BLACK);

	}

	private void presentRespond() {
		graphics.drawPixmap(Assets.bottest, xCorner - width, yCorner - height, calculateSprite * width, yPos,
				width, height);
	}

	public void selectPointsToPlay() {
		selected = data.pointsToPlay[botNumber][rand.nextInt(data.pointsToPlay[botNumber].length)];
		speed = data.speed[botNumber];
		speed += (3 - selected);
	}

	public void ifHit(int x, int y) {

		if (x > 60 && x < 260 && y > 385 && y < 465 && attackOccasion == false) {
			totalMisses++;

		}
		if (x > 60 && x < 260 && y > 385 && y < 465 && attackOccasion == true) {
			totalHits++;
			hacked = true;
			attackOccasion = false; // protects repeat hits
		}

	}

	// ***************************PRESENT*****************************

}
